// Koa 中间件函数：异步函数，接收两个参数，ctx 请求上下文和 next 函数，表示向下执行
// 身份认证中间件，任务是：
// 1、获取请求中的 token 令牌
// 2、校验令牌是否合法
// 3、解析令牌中的用户信息
// 4、将用户信息添加到 ctx 请求上下文上，供 controller 和 service 层使用
// 5、向下执行

const whiteList = ["/register", "/login"];
module.exports = () => {
    // 返回一个中间件函数
    return async (ctx, next) => {
        if (whiteList.includes(ctx.path)) {
            await next();
            return;
        }

        const token = ctx.header.token;
        if (!token) {
            ctx.body = {
                code: 401,
                message: "没有 token 无法完成身份认证",
            };
            return;
        }
        // 看看令牌是否合法，是不是我服务器给你生成的
        try {
            // 校验token是否合法，如果不合法会报错，合法就会返回解密后的用户信息
            const user = ctx.helper.checkToken(token);
            // 添加到请求上下文，以便后面使用用户信息
            ctx.user = user;
        } catch (error) {
            // token 过期错误
            if (error.name === "TokenExpiredError") {
                ctx.body = {
                    code: 401,
                    message: "token已过期，请重新登录",
                };
                return;
            }

            // 不是有效的 token
            if (error.name === "JsonWebTokenError") {
                ctx.body = {
                    code: 401,
                    message: "token不合法",
                };
                return;
            }

            ctx.body = {
                code: 401,
                message: "未知的身份认证错误",
            };
        }

        // 向下执行
        await next();
    };
};
